import React, { Component } from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { Tabs, Empty, Spin } from 'antd';
import MyECharts from '@components/my-echarts';
import cn from 'classnames';
import './index.less';

const TabPane = Tabs.TabPane;

class Top10 extends Component {
  static propTypes = {
    title: PropTypes.string,
    icon: PropTypes.string,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        key: PropTypes.string,
        name: PropTypes.string
      })
    ),
    loader: PropTypes.func,
    className: PropTypes.string,
    iconClassName: PropTypes.string,
    getItemColor: PropTypes.func,
    history: PropTypes.object,
    nameField: PropTypes.string,
    valueField: PropTypes.string,
    onClickItem: PropTypes.func
  };

  static defaultProps = {
    nameField: 'name',
    valueField: 'value'
  };

  constructor(props) {
    super(props);
    this.state = {
      activeKey: _.get(props, 'items[0].key', ''),
      top10: []
    };
  }

  componentDidMount() {
    this.loadTop10();
  }

  loadTop10 = () => {
    const { activeKey } = this.state;
    const { loader, nameField, valueField } = this.props;
    this.setState({ loading: true });
    loader(activeKey, top10 => {
      this.setState(
        {
          top10: top10.filter(i => i && i[nameField] && i[valueField]).slice(0, 10)
        },
        () => {
          this.setState({ loading: false });
        }
      );
    });
  };

  onTabChange = key => {
    this.setState(
      {
        activeKey: key
      },
      this.loadTop10
    );
  };

  renderNameStr = (name = '', reactNode = false) => {
    if (name.length > 60) {
      if (reactNode) {
        return `${name.slice(0, 60)}<br />${name.slice(60)}`;
      }
      return name.slice(0, 60) + '...';
    }
    return name;
  };

  getOption = () => {
    const { top10 } = this.state;
    let { getItemColor, nameField, valueField } = this.props;

    let availCount = top10.length;
    let chartData = top10
      .map(item => item[valueField])
      .concat(new Array(10).fill(''))
      .splice(0, 10);
    let chartName = top10
      .map(item => item[nameField])
      .concat(new Array(10).fill(''))
      .splice(0, 10);
    let colors = top10.map(getItemColor);

    let maxData = Math.ceil(_.max(chartData) * 1.1);
    let maxDatas = new Array(availCount).fill(maxData);

    for (let i = availCount; i <= 10; i++) {
      maxDatas.push({
        value: maxData,
        itemStyle: {
          color: '#ffffff'
        }
      });
    }

    let option = {
      backgroundColor: '#fff',
      color: colors,
      tooltip: {
        formatter: ({ dataIndex }) => {
          if (dataIndex >= availCount) {
            return '';
          }
          return `${this.renderNameStr(chartName[dataIndex], true)}<br/>${chartData[dataIndex]}`;
        }
      },
      grid: {
        left: '10',
        right: '10',
        bottom: '0',
        top: '0',
        containLabel: true
      },
      xAxis: [
        {
          show: false,
          max: maxData
        },
        {
          show: false,
          position: 'top',
          max: maxData
        },
        {
          show: false,
          max: maxData
        }
      ],
      yAxis: {
        type: 'category',
        inverse: true,
        show: false
      },

      series: [
        {
          show: true,
          type: 'bar',
          barGap: '-100%',
          barWidth: '20%',
          z: 3,
          tooltip: false,
          label: {
            color: '#686C78',
            fontSize: 14,
            show: true,
            position: 'insideTopRight',
            backgroundColor: '#ffffff',
            formatter: ({ dataIndex }) => chartData[dataIndex] || '',
            offset: [0, -23]
          },
          itemStyle: {
            color: '#F7F9FC'
          },
          emphasis: {
            color: '#F7F9FC'
          },
          data: maxDatas
        },
        {
          show: true,
          type: 'bar',
          barGap: '-100%',
          barWidth: '20%',
          z: 999,
          data: chartData.map((value, index) => ({ value, itemStyle: { color: colors[index] } }))
        },
        {
          show: true,
          type: 'bar',
          xAxisIndex: 1,
          barGap: '-100%',
          barWidth: '10%',
          itemStyle: {
            normal: {
              barBorderRadius: 200,
              color: 'transparent'
            }
          },
          label: {
            normal: {
              show: true,
              position: [0, '-18'],
              textStyle: {
                fontSize: 14,
                color: '#686C78'
              },
              formatter: ({ dataIndex }) => this.renderNameStr(chartName[dataIndex]) || ''
            }
          },
          data: chartData.map((value, index) => ({ value, label: { color: colors[index] } }))
        }
      ]
    };

    return option;
  };

  onClickItem = e => {
    const { nameField } = this.props;
    const { top10, activeKey } = this.state;
    const data = _.get(top10[e.dataIndex], nameField, '');

    if (data) {
      this.props.onClickItem({ activeKey, value: data });
    }
  };

  render() {
    const { title, items = [], icon, className, iconClassName } = this.props;
    const { activeKey, top10 = [] } = this.state;
    const option = this.getOption();
    return (
      <div className={cn('aa-c-top10', className)}>
        <div className="top10__header">
          <span className="value">{title}</span>
          <span className={cn('img-wrapper', iconClassName)}>
            <img src={icon} />
          </span>
        </div>
        <div className="top10__body">
          <Spin tip="加载中" spinning={this.state.loading}>
            <Tabs activeKey={activeKey} onChange={this.onTabChange}>
              {items.map(({ name, key }) => (
                <TabPane key={key} tab={name}>
                  {top10.length ? (
                    <MyECharts option={option} onClick={this.onClickItem} />
                  ) : (
                    <Empty
                      description={this.state.loading ? ' ' : '暂无数据'}
                      image={Empty.PRESENTED_IMAGE_SIMPLE}
                    />
                  )}
                </TabPane>
              ))}
            </Tabs>
          </Spin>
        </div>
      </div>
    );
  }
}

export default Top10;
